#ifndef UTIL_SCOPEGUARDKEN_H_
#define UTIL_SCOPEGUARDKEN_H_

#include <functional>
#include <type_traits>

namespace toolkit {

// 将 onceToken 重命名为 ScopeGuard，更能表达其用途
class ScopeGuard {
public:
    using task = std::function<void(void)>;

    template<typename FUNC>
    ScopeGuard(const FUNC &onConstructed, task onDestructed = nullptr) {
        onConstructed();
        _onDestructed = std::move(onDestructed);
    }

    ScopeGuard(std::nullptr_t, task onDestructed = nullptr) {
        _onDestructed = std::move(onDestructed);
    }

    ~ScopeGuard() {
        if (_onDestructed) {
            _onDestructed();
        }
    }

private:
    ScopeGuard() = delete;
    ScopeGuard(const ScopeGuard &) = delete;
    ScopeGuard(ScopeGuard &&) = delete;
    ScopeGuard &operator=(const ScopeGuard &) = delete;
    ScopeGuard &operator=(ScopeGuard &&) = delete;

private:
    task _onDestructed;
};

} /* namespace toolkit */
#endif /* UTIL_SCOPEGUARDKEN_H_ */